package co.com.losalpes.marketplace.picontract.beans;

import co.com.losalpes.marketplace.picontract.bo.ComercioBO;
import co.com.losalpes.marketplace.picontract.bo.ContratoBO;
import co.com.losalpes.marketplace.picontract.bo.FabricanteBO;
import co.com.losalpes.marketplace.picontract.bo.FabricanteProductoBO;
import co.com.losalpes.marketplace.picontract.bo.ProductoBO;
import co.com.losalpes.marketplace.picontract.entities.Comercio;
import co.com.losalpes.marketplace.picontract.entities.Contrato;
import co.com.losalpes.marketplace.picontract.entities.Fabricante;
import co.com.losalpes.marketplace.picontract.entities.Oferta;
import co.com.losalpes.marketplace.picontract.entities.Producto;
import co.com.losalpes.marketplace.picontract.entities.PurchaseOrder;
import co.com.losalpes.marketplace.picontract.entities.Subasta;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

@Stateless
public class ContractBean
  implements ContractLocal, ContractRemote
{

  @PersistenceContext
  private EntityManager em;

  public ContratoBO consultarContratoPorRadicado(ContratoBO contratoBO)
  {
    Query q = this.em.createNamedQuery("consultarContratoPorRadicado");
    q.setParameter("numeroRadicacion", contratoBO.getNumeroRadicacion());
    Contrato contratoAux = (Contrato)q.getSingleResult();
    return contratoAux.toBO();
  }

  public List<FabricanteProductoBO> consultarFabricantes(ComercioBO comercioBO)
  {
    List listadoFabricantes = new LinkedList();

    Query q = this.em.createNamedQuery("consultarOrdenPorComercio");
    q.setParameter("nitComercio", comercioBO.getNit());

    List<PurchaseOrder> purchaseAuxList = q.getResultList();

    for (PurchaseOrder purchaseOrder : purchaseAuxList) {
      Query q2 = this.em.createNamedQuery("consultarSubastaPorOrdenCompra");
      q2.setParameter("idPO", purchaseOrder.getId());

      Subasta subastaAux = (Subasta)q2.getSingleResult();
      List<Fabricante> fabricantes = subastaAux.getFabricantes();
      Collection<Oferta> ofertas = subastaAux.getOfertas();

      FabricanteProductoBO fabProdBO = new FabricanteProductoBO();
      HashSet<ProductoBO> listProductosAux = new HashSet();

      for (Fabricante fabricante : fabricantes) {
        fabProdBO.setFabricante(fabricante.toBO());
        for (Oferta oferta : ofertas) {
          if (fabricante.equals(oferta.getFabricante()))
          {
            ProductoBO producto = oferta.getProductoOfrecido().toBO();
            producto.setPrecio(Long.valueOf(oferta.getValor().longValue()));
            listProductosAux.add(producto);
          }
        }
        List listProductos = new LinkedList();
        for (ProductoBO productoBO : listProductosAux) {
          listProductos.add(productoBO);
        }
        fabProdBO.setProductos(listProductos);

        if (!listProductosAux.isEmpty())
          listadoFabricantes.add(fabProdBO);
      }
    }
    return listadoFabricantes;
  }

  public ContratoBO crearContrato(ContratoBO contrato)
  {
    Query q = this.em.createNamedQuery("getComercioByNit");
    q.setParameter("nit", contrato.getComercio().getNit());
    Comercio comercio = (Comercio)q.getSingleResult();

    Query q2 = this.em.createNamedQuery("getFabricanteFromNit");
    q2.setParameter("nit", contrato.getFabricante().getNit());
    List fabricantes = q2.getResultList();

    Query q4 = this.em.createNamedQuery("findByNombre");
    q4.setParameter("nombre", contrato.getProducto().getNombre());
    List productos = q4.getResultList();

    Contrato c = new Contrato();
    c.setCantidad(contrato.getCantidad());
    c.setComercio_id(comercio);
    c.setDuracionContrato(contrato.getDuracionContrato());
    c.setEstado(contrato.getEstado());
    c.setFabricante_id((Fabricante)fabricantes.get(0));
    c.setProducto((Producto)productos.get(0));
    c.setFechaAprobacionComercio(contrato.getFechaAprobacionComercio());
    c.setFechaAprobacionFabricante(contrato.getFechaAprobacionFabricante());
    c.setFechaInicio(contrato.getFechaInicio());
    c.setNumeroCiclos(contrato.getNumeroCiclos());

    c.setPeriodicidad(contrato.getPeriodicidad());
    c.setValorContrato(contrato.getValorContrato());
    c.setMotivoC(contrato.getMotivoCancelacion());
    c.setValorContratoComercio(contrato.getValorContratoComercio());
    this.em.persist(c);
    return c.toBO();
  }

  public ContratoBO actualizarContrato(ContratoBO contrato)
  {
    Comercio comercio = new Comercio();
    Fabricante fabricante = new Fabricante();
    Contrato c = new Contrato();

    if (!contrato.getComercio().getNit().equals("")) {
      Query q = this.em.createNamedQuery("getComercioByNit");
      q.setParameter("nit", contrato.getComercio().getNit());
      comercio = (Comercio)q.getSingleResult();
    }

    if (!contrato.getFabricante().getNit().equals("")) {
      Query q2 = this.em.createNamedQuery("getFabricanteFromNit");
      q2.setParameter("nit", contrato.getFabricante().getNit());
      fabricante = (Fabricante)q2.getSingleResult();
    }

    Query q4 = this.em.createNamedQuery("consultarContratoPorRadicado");
    q4.setParameter("numeroRadicacion", contrato.getNumeroRadicacion());
    c = (Contrato)q4.getSingleResult();

    c.setCantidad(contrato.getCantidad() != null ? contrato.getCantidad() : c.getCantidad());
    c.setComercio_id(comercio.getNit() != null ? comercio : c.getComercio());
    c.setDuracionContrato(contrato.getDuracionContrato() != null ? contrato.getDuracionContrato() : c.getDuracionContrato());
    c.setEstado(contrato.getEstado() != null ? contrato.getEstado() : c.getEstado());
    c.setFabricante_id(fabricante.getNit() != null ? fabricante : c.getFabricante());
    c.setFechaAprobacionComercio(contrato.getFechaAprobacionComercio() != null ? contrato.getFechaAprobacionComercio() : c.getFechaAprobacionComercio());
    c.setFechaAprobacionFabricante(contrato.getFechaAprobacionFabricante() != null ? contrato.getFechaAprobacionFabricante() : c.getFechaAprobacionFabricante());
    c.setFechaInicio(contrato.getFechaInicio() != null ? contrato.getFechaInicio() : c.getFechaInicio());
    c.setNumeroCiclos(contrato.getNumeroCiclos() != null ? contrato.getNumeroCiclos() : c.getNumeroCiclos());
    c.setNumeroRadicacion(contrato.getNumeroRadicacion() != null ? contrato.getNumeroRadicacion() : c.getNumeroRadicacion());
    c.setPeriodicidad(contrato.getPeriodicidad() != null ? contrato.getPeriodicidad() : c.getPeriodicidad());
    c.setValorContrato(contrato.getValorContrato() != null ? contrato.getValorContrato() : c.getValorContrato());
    c.setMotivoC(contrato.getMotivoCancelacion() != null ? contrato.getMotivoCancelacion() : c.getMotivoC());
    c.setValorContratoComercio(contrato.getValorContratoComercio() != null ? contrato.getValorContrato() : c.getValorContrato());
    this.em.merge(c);
    return c.toBO();
  }

  public List<ContratoBO> consultarContratoPorComercio(String nit, String estado) {
    Query q = this.em.createNamedQuery("consultarContratoComercioNitEstado");
    q.setParameter("nit", nit);
    q.setParameter("estado", estado);

    List contratosBO = new ArrayList();
    List<Contrato> contratos = q.getResultList();
    for (Contrato contrato : contratos) {
      contratosBO.add(contrato.toBO());
    }

    return contratosBO;
  }

  public List<ContratoBO> consultarContratoPorFabricante(String nit, String estado) {
    Query q = this.em.createNamedQuery("consultarContratoFabricanteNitEstado");
    q.setParameter("nit", nit);
    q.setParameter("estado", estado);

    List contratosBO = new ArrayList();
    List<Contrato> contratos = q.getResultList();
    for (Contrato contrato : contratos) {
      contratosBO.add(contrato.toBO());
    }

    return contratosBO;
  }
}